package utils

import (
	"context"
	"encoding/json"
	"github.com/redis/go-redis/v9"
	"time"
)

// RedisUtil Redis工具类
type RedisUtil struct {
	Ctx         context.Context
	RedisClient *redis.Client
}

// NewRedisUtil 创建Redis工具类实例
func NewRedisUtil(r *redis.Client) *RedisUtil {
	return &RedisUtil{
		Ctx:         context.Background(),
		RedisClient: r,
	}
}

// Set 设置键值对
func (r *RedisUtil) Set(key string, value interface{}, expiration time.Duration) error {
	// 将value转换为JSON字符串
	jsonValue, err := json.Marshal(value)
	if err != nil {
		return err
	}
	return r.RedisClient.Set(r.Ctx, key, jsonValue, expiration).Err()
}

// Get 获取值
func (r *RedisUtil) Get(key string, value interface{}) error {
	jsonValue, err := r.RedisClient.Get(r.Ctx, key).Result()
	if err != nil {
		return err
	}
	return json.Unmarshal([]byte(jsonValue), value)
}

// Delete 删除键
func (r *RedisUtil) Delete(key string) error {
	return r.RedisClient.Del(r.Ctx, key).Err()
}

// Exists 检查键是否存在
func (r *RedisUtil) Exists(key string) (bool, error) {
	result, err := r.RedisClient.Exists(r.Ctx, key).Result()
	return result > 0, err
}

// SetTaskStatus 设置任务状态
func (r *RedisUtil) SetTaskStatus(taskID string, status string, expiration time.Duration) error {
	key := "task_status:" + taskID
	return r.Set(key, status, expiration)
}

// GetTaskStatus 获取任务状态
func (r *RedisUtil) GetTaskStatus(taskID string) (string, error) {
	var status string
	key := "task_status:" + taskID
	err := r.Get(key, &status)
	return status, err
}

// SetHash 设置哈希表字段
func (r *RedisUtil) SetHash(key, field string, value interface{}, expiration time.Duration) error {
	jsonValue, err := json.Marshal(value)
	if err != nil {
		return err
	}

	if err := r.RedisClient.HSet(r.Ctx, key, field, jsonValue).Err(); err != nil {
		return err
	}

	if expiration > 0 {
		return r.RedisClient.Expire(r.Ctx, key, expiration).Err()
	}
	return nil
}

// GetHash 获取哈希表字段
func (r *RedisUtil) GetHash(key, field string, value interface{}) error {
	jsonValue, err := r.RedisClient.HGet(r.Ctx, key, field).Result()
	if err != nil {
		return err
	}
	return json.Unmarshal([]byte(jsonValue), value)
}

// DeleteHash 删除哈希表字段
func (r *RedisUtil) DeleteHash(key string, fields ...string) error {
	return r.RedisClient.HDel(r.Ctx, key, fields...).Err()
}

// SetList 将值插入列表
func (r *RedisUtil) SetList(key string, value interface{}, expiration time.Duration) error {
	jsonValue, err := json.Marshal(value)
	if err != nil {
		return err
	}

	if err := r.RedisClient.RPush(r.Ctx, key, jsonValue).Err(); err != nil {
		return err
	}

	if expiration > 0 {
		return r.RedisClient.Expire(r.Ctx, key, expiration).Err()
	}
	return nil
}

// GetList 获取列表所有元素
func (r *RedisUtil) GetList(key string) ([]string, error) {
	return r.RedisClient.LRange(r.Ctx, key, 0, -1).Result()
}

// IncrBy 增加指定的整数
func (r *RedisUtil) IncrBy(key string, value int64) (int64, error) {
	return r.RedisClient.IncrBy(r.Ctx, key, value).Result()
}

// DecrBy 减少指定的整数
func (r *RedisUtil) DecrBy(key string, value int64) (int64, error) {
	return r.RedisClient.DecrBy(r.Ctx, key, value).Result()
}
